package com.cy.pj.notice.web.controller;

import com.cy.pj.commom分页工具类和异常定义类.util分页工具类.PageUtil分页工具类;
import com.cy.pj.log.annotation.RequiredLog;
import com.cy.pj.notice.web.pojo响应标准的设计.JsonResult;
import com.cy.pj.notice.pojo插件lombok注解代替set和get方法.SysNotice;
import com.cy.pj.notice.service.impl.SysNoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
//sca-notice依赖于sca-common

/**
 * 此对象为公告模块控制层处理器对象
 * 1.请求url设计
 * 区别：Get请求--参数少时用，手写的。 Post请求--参数多时用，form表单自动拼接
 * 1),条件查询（请求方式Get,请求url"/not/"）
 * 2),新增公告(请求方式--post,请求url-"/not/")
 * 3),基于id查询(请求方式--Get,请求url-"/not/{id}")
 * 4),更新公告(请求方式-Put,请求url-"/not/")
 * 5)，删除公告(请求方式-Delete,请求url-"/not/{id}")
 * 2.请求参数设计
 * 1)参数传递方式
 * 1.1)将请求参数通过url进行传递
 * 1.1.1)http://ip:port/?titile=my&type=1
 * 1.1.2)http://ip:port/10
 * 1.2)请求参数通过请求体进行传递
 * 1.2.1){“title”:“study spring boot”,“content”:“study...”,...}
 * <p>
 * 1.2)服务端接收请求参数
 * 1.2.1)直接量--8种基本数据类型，字符串，日期
 * 1.2.2)pojo对象--但是需要提供和参数名对应的set方法
 * 1.2.3)map对象--前提是必须使用@RequestParam或@RequestBody注解对参数进行描述
 * <p>
 * 1.3)方法参数的描述
 * 1.3.1)@PathVariable--用于获取请求url中{}内部的变量
 * 1.3.2)@RequestBody--用于获取请求体中json格式的数据
 * 1.3.3)@RequestParam--用于获取非json格式的请求参数数据
 * 1.3.4)@DateTimeFormat--用于设置可以接收的日期格式字符串
 * <p>
 * <p>
 * <p>
 * 2,响应标准设计(状态，消息，数据)：JsonResult
 */
@RestController //包含了@ResponseBody和 @Controller
@RequestMapping("/notice/")
public class SysNoticeController {
    @Autowired
    private SysNoticeService sysNoticeService;

    /**
     * 基于id执行删除业务
     *
     * @param id
     * @return
     */
    @RequiredLog(operation = "删除公告")
    @DeleteMapping("{id}")
    public JsonResult doDeleteById(@PathVariable Long... id) {
        //try {
        return new JsonResult(sysNoticeService.deleteById(id));
        //} catch (Exception e) {
        // return new JsonResult(e);
        // }
    }

    /**
     * 更新公告信息
     *
     * @param sysNotice 封装了公告信息的参数对像。
     * @return
     */
    @PutMapping
    public JsonResult doUpdateNotice(@RequestBody SysNotice sysNotice) {
        sysNoticeService.updateNotice(sysNotice);
        return new JsonResult("ok");
    }

    /**
     * rest风格的url中允许使用变量，但这+个变量需要使用{}括起来
     * 当我们在方法参数中需要这个变量的值时，可以使用@PathVariable对
     * 方法参数进行描述
     * 访问url: http://localhost/notice/2
     *
     * @param id
     * @return
     */
    @GetMapping("{id}") //{}里面的参数名字要和方法里面的参数名一样
    public JsonResult doFindById(@PathVariable Long id) {
        //try {
        return new JsonResult(sysNoticeService.findById(id));
        // } catch (Exception e) {
        //return new JsonResult(e);
        //}
    }

    /**
     * 新增公告信息
     *
     * @param sysNotice 封装客户端提交的通告信息，假如使用@RequestBody对参数
     *                  进行描述 ，客户端可以向服务端传递json格式的字符串参数，服务端拿到字符串
     *                  以后，会将json字符串转为参数类型的对象(这个过程还可以理解为json反序列化)
     *                  注意：一个Controller方法中只能有一个参数使用@RequestBody注解进行描述
     * @return
     */
    @PostMapping
    public JsonResult daSaveNotice(@RequestBody SysNotice sysNotice) {
        sysNoticeService.saveNotice(sysNotice);
        return new JsonResult("OK");//json序列化
    }

    /**
     * 处理客户端的查询请求：
     * 1，不带参数的请求url:http://localhost/not/
     * 不带参数就默认查询所有的了(80端口可以省略)
     * 2,带参数的请求url：http://localhost/not/?type=1&title=my
     * 底层会将参数用set方法注入到pojo里面执行
     */
    @RequiredLog(operation = "查询通告")
    @GetMapping
    public JsonResult doFindNotices(SysNotice sysNotice) {
        /**步骤：PageHelper-分页插件
         * 1,启动拦截器分页查询，并设置每页有3条数据，起始页是 1，页码值不能为 0
         * 2，在通过它的API找到，拼接，并执行查询sql语句(参数是接口，用匿名内部类实现接口ISelect方法)
         *3，将执行的结果返回分页对象pageInfo，再用响应标准返回客户端
         */
        /**详细写法：PageInfo<SysNotice> pageInfo=PageHelper.startPage(1, 3)
         //执行查询
         .doSelectPageInfo(new ISelect() {
        @Override public void doSelect() {
        sysNoticeService.findNotice(sysNotice);
        }
        });
         return new JsonResult(pageInfo);
         */

        /**
         * 上面的太死了，不能接受请求
         * 以下封装了分页启动PageHelper.startPage()的代码，可以获取请求对象分页查询了
         * 作用：把数据库里的数据分页--?要查第几页&每页几条数据-网页输入：http://localhost/not/?pageCurrent=1&pageSize=3
         */
        return new JsonResult(PageUtil分页工具类.startPage()
                .doSelectPageInfo(() -> //lambda写法，JDK8.0的写法-只有一个方法时，不用匿名内部类，直接用箭头表达式
                        sysNoticeService.findNotice(sysNotice)
                ));

//这个结果会返给谁？--调用方：DispatcherServlet
//方法调用方拿到方法执行结果以后会调用相关的api将结果转换为json格式字符串
// 最后通过Response对象(@RestController包含了这个)，将字符串响应到客户端
    }
}
